package com.wangzhen.spring.bean.scope;

import com.wangzhen.spring.ioc.dependcy.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

public class BeanScopeDemo {
    // 定义3个 shared bean
    @Autowired
    @Qualifier("singletonUser")
    private User singletonUser1;
    @Autowired
    @Qualifier("singletonUser")
    private User singletonUser2;
    @Autowired
    @Qualifier("singletonUser")
    private User singletonUser3;


    // 定义3个 independent bean
    @Autowired
    @Qualifier("prototypeUser")
    private User prototypeUser1;
    @Autowired
    @Qualifier("prototypeUser")
    private User prototypeUser2;
    @Autowired
    @Qualifier("prototypeUser")
    private User prototypeUser3;

    // spring 默认作用域就是singleton
    @Bean
    public User singletonUser() {
        User user = new User();
        user.setName(String.valueOf(System.nanoTime()));
        return user;
    }

    // 指定作用域是 prototype
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public User prototypeUser() {
        User user = new User();
        user.setName(String.valueOf(System.nanoTime()));
        return user;
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(BeanScopeDemo.class);
        // 启动应用上下文
        applicationContext.refresh();

        //
        scopeBeanLookup(applicationContext);

        scopeBeanInject(applicationContext);

        BeanDefinition singletonUser = applicationContext.getBeanDefinition("singletonUser");
        System.out.println(singletonUser);

        BeanDefinition prototypeUser = applicationContext.getBeanDefinition("prototypeUser");
        System.out.println(prototypeUser);

        // 关闭应用上下文
        applicationContext.close();
    }

    private static void scopeBeanInject(AnnotationConfigApplicationContext applicationContext) {
        BeanScopeDemo bean = applicationContext.getBean(BeanScopeDemo.class);
        System.out.println(bean.singletonUser1);
        System.out.println(bean.singletonUser2);
        System.out.println(bean.singletonUser3);

        System.out.println(bean.prototypeUser1);
        System.out.println(bean.prototypeUser2);
        System.out.println(bean.prototypeUser3);
    }

    private static void scopeBeanLookup(AnnotationConfigApplicationContext applicationContext) {
        for (int i = 0; i < 3; i++) {
            System.out.println("singletonUser: "+applicationContext.getBean("singletonUser"));
            System.out.println("prototypeUser: "+applicationContext.getBean("prototypeUser"));
        }
    }
}
